// console.log(1)
// const test = () => {
//   console.log(3)
//   return 4
// }
// const promise = new Promise((resole, reject) => {
//   console.log(2)
//   resole(test())
// })
// promise.then(res => {
//   console.log(res)
// }) 
// console.log(5)


// 先定义三个状态

const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';



class MyPromise{
  // executor: 传入的执行器函数，会立即执行
  constructor(executor) {

    this.value = null;  // 接收成功的值
    this.reason = null; // 接受失败的原因
    this.status = PENDING; // 初始状态
    this.onFulfilledCallback = []; // 储存成功的回调
    this.onRejectedCallback = []; // 存储失败的回调

    executor(this.resolve, this.reject) // 执行器执行
  }

  resolve = (value) => {
    if(this.status !== PENDING) return ; // 只有状态为等待才能修改
    this.status = FULFILLED; // 状态改为成功
    this.value = value; // 保存成功的值
    this.onFulfilledCallback.forEach(callback => callback()); // 状态改变，执行onFulfilledCallback数组储存的函数
  }

  reject = (reason) => {
    if(this.status !== PENDING) return ; // 只有状态为等待才能修改
    this.status = REJECTED; // 状态改为失败
    this.reason = reason; // 保存失败的值
    this.onRejectedCallback.forEach(callback => callback()); // 状态改变，执行onRejectedCallback数组储存的函数
  }

  then(onFulfilled, onRejected) {
    const resPromise = (p, s, resolve, reject) => {
      if(p === s) {
        return reject(new TypeError('Chaining cycle detected for promise'));
      }
      if(s instanceof MyPromise) {
        s.then(resolve, reject)
      }else{
        resolve(s)
      }
    }

    let promise = new MyPromise((resolve, reject) => {
      if(this.status === FULFILLED) {
        setTimeout(() => { // then是异步的
          let s = onFulfilled(this.value);
          resPromise(promise, s, resolve, reject); // 执行成功的回调
        }, 0)
      } else if(this.status === REJECTED){
        setTimeout(() => { // then是异步的
          let s = onRejected(this.reason);
          resPromise(promise, s, resolve, reject); // 执行失败的回调
        }, 0)
        
      }else{
        this.onFulfilledCallback.push(() => {
          setTimeout(() => {
            let s = onFulfilled(this.value); // 执行成功的回调
            resPromise(promise, s, resolve, reject);
          }), 0
        })
        this.onRejectedCallback.push(() => {
          setTimeout(() => {
            let s = onRejected(this.reason); // 执行失败的回调
            resPromise(promise, s, resolve, reject);
          }, 0)
        })
      }
    })
    return promise;
  }

  catch(onRejected) {
    return this.then(undefined, onRejected);
  }

  static resolve(value) {
    return new MyPromise((resolve, reject) => {
      if(resolve instanceof MyPromise) {
        value.then(resolve, reject);
      }else {
        resolve(value);
      }
    })
  }

  static reject(reason) {
    return new MyPromise((resolve, reject) => {
      resolve(reason);
    })
  }

  static all(promises) {
    let len = promises.length;
    let arr = []
    promises = promises.map(p => p instanceof MyPromise ? p : this.resolve(p)); // 不是promise实例就先转化为promise实例
    return new MyPromise((resolve, reject) => {
      for(let i = 0; i < len; i++) {
        promises[i].then(res => {
          arr[i] = res;
          if(arr.length === len) { // 等promises数组所有的实例都返回成功，才resolve
            resolve(arr);
          }
        }, (err) => {
          reject(err); // 只要有一个实例失败，就返回失败
        })
      }
    })
  }

  static race(promises) {
    let len = promises.length;
    promises = promises.map(p => p instanceof MyPromise ? p : this.resolve(p));
    return new MyPromise((resolve, reject) => {
      for(let i = 0; i < len; i++) {
        promises[i].then((res) => resolve(res), (err) => reject(err)) // 无论成功与否，只返回第一个完成的promise
      }
    })
  }

  static allSettled(promises) {
    let len = promises.length;
    let arr = []
    promises = promises.map(p => p instanceof MyPromise ? p : this.resolve(p));
    return new MyPromise((resolve, reject) => {
      for(let i = 0; i < len; i++) {
        promises[i].then((res) => {
          arr[i] = {
            status: 'fulfilled',
            value: res
          }
          if(arr.length === len) resolve(arr); // 当数组遍历完才更改promise状态为成功
        }, (err) => {
          arr[i] = {
            status: 'rejected',
            value: err
          };
          if(arr.length === len) resolve(arr); // 当数组遍历完才更改promise状态为成功
        })
      }
    })
  }

  static any(promises) {
    let len = promises.length;
    let arr = []
    promises = promises.map(p => p instanceof MyPromise ? p : this.resolve(p));
    for(let i = 0; i < len; i++) {
      promises[i].then(res => {
        resolve(res); // 只要有一个promise成功，就resole，返回成功状态
      }, (err) => {
        arr[i] = err;
        if(arr.length === len) { // 等promises数组所有的实例都返回失败，才reject， 返回失败状态
          reject(arr);
        }
      })
    }
  }




}

// 测试

// const promise = new MyPromise((resole, reject) => {
//   // resole('执行成功回调')
//   reject('执行失败回调')
// })


// promise.then((res) => {
//   console.log(res)
//   return '链式调用'
// }, (err) => {
//   console.log(err)
// }).then((res) => {
//   console.log(res)
// })
// console.log('22222222')

// promise.catch((err) => {
//   console.log(err)
//   return 2112
// }).then(res => {
//   console.log(res)
// })





